1 // Sample solution of NWERC-2004-Pipes by Ola Hugosson
7 #define D(x) cout << #x " = " << (x) << endl
12 #define FEDECOST 0xfede
13 #define MAXSTATES 5798 // pre-calculated
14 #define GETTYPE(sidx,i) (((sidx)>>(2*(i)))&3)
15 #define SETTYPE(type,i) (((type)<<(2*(i))))
17 int state
[MAXSTATES
], newstate
[MAXSTATES
], map
[MAXSTATES
];
18 short invmap
[1<<(2*11)];
20 // calculate a map used to enumerate all valid boundaries
21 int genmap(int c
, int n
, int i
, int nest
, int sidx
)
23 printf("c = %d, n = %d, i = %d, nest = %d, sidx = %x\n", c
, n
, i
, nest
, sidx
);
24 if (nest
>=0 && i
<=c
) {
25 n
=genmap(c
,n
,i
+1,nest
, sidx
|SETTYPE(NONE
,i
));
26 n
=genmap(c
,n
,i
+1,nest
+1,sidx
|SETTYPE(IN
,i
));
27 n
=genmap(c
,n
,i
+1,nest
-1,sidx
|SETTYPE(OUT
,i
));
31 printf("mask = %X, nest = 0\n", sidx
);
38 int floors
, r
, c
, x
, y
, n
, i
, j
, sidx
, left
, up
, right
, down
, cost
, prevcost
;
39 char lrwall
[30],udwall
[30];
40 for( scanf("%d",&floors
); floors
--;) {
41 scanf("%d %d\n",&r
,&c
);
42 gets(udwall
); //dummy-input
45 for (int i
= 0; i
< n
; ++i
){
47 printf("mask = %X\n", mask
);
48 for (int j
= 0; j
<= c
; ++j
){
49 int what
= GETTYPE(mask
, j
);
69 newstate
[invmap
[0]]=0;
79 static const char lut
[3][3][3] =
80 {{{1, IN
, OUT
}, {2, NONE
, IN
}, {2, NONE
, OUT
}},
81 {{2, NONE
, IN
}, {1, NONE
, NONE
}, {0, NONE
, NONE
}}, // the 0 prevents internal loops
82 {{2, NONE
, OUT
}, {1, NONE
, NONE
}, {1, NONE
, NONE
}}};
83 prevcost
= (x
>0 ? state
[i
] : ((map
[i
]&3)==NONE
) ? state
[invmap
[map
[i
]>>2]] : FEDECOST
);
84 if (prevcost
>=FEDECOST
)
85 continue; // speed up somewhat
88 up
=GETTYPE(sidx
,x
+1);
89 for(j
=0; j
<lut
[left
][up
][0]; j
++) {
90 down
=lut
[left
][up
][1+j
];
91 right
=lut
[left
][up
][2-j
];
92 cost
= prevcost
+ (right
==NONE
? 0 : lrwall
[2*x
+2]-'0') +
93 (down
==NONE
? 0 : udwall
[2*x
+1]-'0');
94 if (left
==up
&& left
!=NONE
) { // find matching IN/OUT pair
95 int nest
=0, xx
=(left
==OUT
)? x
: x
+1;
96 while(nest
+= GETTYPE(sidx
,xx
)==OUT
? -1 : GETTYPE(sidx
,xx
)==IN
? +1 : 0)
97 xx
+= nest
<0 ? -1 : 1;
98 sidx
^= SETTYPE(3,xx
); // toggle IN<->OUT
100 sidx
= sidx
& ~SETTYPE(15,x
) | SETTYPE(down
,x
) | SETTYPE(right
,x
+1);
101 if (cost
<newstate
[invmap
[sidx
]])
102 newstate
[invmap
[sidx
]]=cost
;
107 printf("%d\n",state
[invmap
[(IN
<<(2*c
-2))|(OUT
<<(2*c
))]]);